import { Request, Response, NextFunction } from 'express';
import { prisma } from '../../config/database';
import { BaseController } from '../../utils/autoBind';
import { ResponseUtils } from '../../utils/responseUtils';
import { BUSINESS_ERROR_CODES } from '../../utils/errorCodes';
import { VALIDATION_ERROR_CODES } from '../../utils/errorCodes';

export class ActivityController extends BaseController {
  // 创建活动
  async createActivity(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { name, description, startTime, endTime, bannerImage, rules, maxVotesPerUser } = req.body;

      // 检查时间段是否冲突
      const conflictingActivity = await prisma.activity.findFirst({
        where: {
          status: 'ACTIVE',
          OR: [
            {
              AND: [
                { startTime: { lte: new Date(startTime) } },
                { endTime: { gt: new Date(startTime) } }
              ]
            },
            {
              AND: [
                { startTime: { lt: new Date(endTime) } },
                { endTime: { gte: new Date(endTime) } }
              ]
            },
            {
              AND: [
                { startTime: { gte: new Date(startTime) } },
                { endTime: { lte: new Date(endTime) } }
              ]
            }
          ]
        }
      });

      if (conflictingActivity) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ACTIVITY_TIME_CONFLICT, '该时间段已存在活动');
        return;
      }

      const activity = await prisma.activity.create({
        data: {
          name,
          description,
          startTime: new Date(startTime),
          endTime: new Date(endTime),
          bannerImage,
          rules,
          maxVotesPerUser: maxVotesPerUser || 1
        }
      });

      ResponseUtils.success(res, activity, '活动创建成功');
    } catch (error) {
      next(error);
    }
  }

  // 获取活动列表
  async getActivities(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { page = 1, limit = 20, status, search } = req.query;
      const pageNum = parseInt(page as string);
      const limitNum = parseInt(limit as string);
      const skip = (pageNum - 1) * limitNum;

      const where: any = {};
      if (status) {
        where.status = status;
      }
      if (search) {
        where.OR = [
          { name: { contains: search as string } },
          { description: { contains: search as string } }
        ];
      }

      const [activities, total] = await Promise.all([
        prisma.activity.findMany({
          where,
          skip,
          take: limitNum,
          orderBy: { createdAt: 'desc' },
          include: {
            _count: {
              select: {
                activityArtists: true,
                votes: true
              }
            }
          }
        }),
        prisma.activity.count({ where })
      ]);

      ResponseUtils.paginated(res, activities, total, pageNum, limitNum, '获取活动列表成功');
    } catch (error) {
      next(error);
    }
  }

  // 获取活动详情
  async getActivity(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const activityId = parseInt(id);

      const activity = await prisma.activity.findUnique({
        where: { id: activityId },
        include: {
          activityArtists: {
            include: {
              artist: {
                select: {
                  id: true,
                  name: true,
                  avatar: true,
                  description: true
                }
              }
            },
            orderBy: { sortOrder: 'asc' }
          },
          _count: {
            select: {
              votes: true
            }
          }
        }
      });

      if (!activity) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ACTIVITY_NOT_FOUND, '活动不存在');
        return;
      }

      ResponseUtils.success(res, activity, '获取活动详情成功');
    } catch (error) {
      next(error);
    }
  }

  // 更新活动
  async updateActivity(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { name, description, startTime, endTime, status, bannerImage, rules, maxVotesPerUser } = req.body;
      const activityId = parseInt(id);

      const existingActivity = await prisma.activity.findUnique({
        where: { id: activityId }
      });

      if (!existingActivity) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ACTIVITY_NOT_FOUND, '活动不存在');
        return;
      }

      // 如果修改了时间，检查冲突
      if (startTime || endTime) {
        const newStartTime = startTime ? new Date(startTime) : existingActivity.startTime;
        const newEndTime = endTime ? new Date(endTime) : existingActivity.endTime;

        const conflictingActivity = await prisma.activity.findFirst({
          where: {
            id: { not: activityId },
            status: 'ACTIVE',
            OR: [
              {
                AND: [
                  { startTime: { lte: newStartTime } },
                  { endTime: { gt: newStartTime } }
                ]
              },
              {
                AND: [
                  { startTime: { lt: newEndTime } },
                  { endTime: { gte: newEndTime } }
                ]
              },
              {
                AND: [
                  { startTime: { gte: newStartTime } },
                  { endTime: { lte: newEndTime } }
                ]
              }
            ]
          }
        });

        if (conflictingActivity) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ACTIVITY_TIME_CONFLICT, '该时间段已存在其他活动');
          return;
        }
      }

      // 构建更新数据，过滤掉undefined值
      const updateData: any = {};
      if (name !== undefined) updateData.name = name;
      if (description !== undefined) updateData.description = description;
      if (startTime !== undefined) updateData.startTime = new Date(startTime);
      if (endTime !== undefined) updateData.endTime = new Date(endTime);
      if (status !== undefined) updateData.status = status;
      if (bannerImage !== undefined) updateData.bannerImage = bannerImage;
      if (rules !== undefined) updateData.rules = rules;
      if (maxVotesPerUser !== undefined) updateData.maxVotesPerUser = maxVotesPerUser;

      const updatedActivity = await prisma.activity.update({
        where: { id: activityId },
        data: updateData
      });

      ResponseUtils.success(res, updatedActivity, '活动更新成功');
    } catch (error) {
      next(error);
    }
  }

  // 删除活动
  async deleteActivity(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const activityId = parseInt(id);

      // 检查是否有投票数据
      const voteCount = await prisma.vote.count({
        where: { activityId }
      });

      if (voteCount > 0) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ACTIVITY_HAS_VOTES, '该活动已有投票数据，无法删除');
        return;
      }

      await prisma.activity.delete({
        where: { id: activityId }
      });

      ResponseUtils.success(res, null, '活动删除成功');
    } catch (error) {
      next(error);
    }
  }

  // 添加艺人到活动
  async addArtistToActivity(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { activityId, artistId, sortOrder = 0 } = req.body;

      // 检查活动是否存在
      const activity = await prisma.activity.findUnique({
        where: { id: parseInt(activityId) }
      });

      if (!activity) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ACTIVITY_NOT_FOUND, '活动不存在');
        return;
      }

      // 检查艺人是否存在
      const artist = await prisma.artist.findUnique({
        where: { id: parseInt(artistId) }
      });

      if (!artist) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ARTIST_NOT_FOUND, '艺人不存在');
        return;
      }

      // 检查是否已经添加
      const existingRelation = await prisma.activityArtist.findUnique({
        where: {
          activityId_artistId: {
            activityId: parseInt(activityId),
            artistId: parseInt(artistId)
          }
        }
      });

      if (existingRelation) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ARTIST_ALREADY_IN_ACTIVITY, '该艺人已在此活动中');
        return;
      }

      const activityArtist = await prisma.activityArtist.create({
        data: {
          activityId: parseInt(activityId),
          artistId: parseInt(artistId),
          sortOrder: parseInt(sortOrder)
        },
        include: {
          artist: {
            select: {
              id: true,
              name: true,
              avatar: true
            }
          }
        }
      });

      ResponseUtils.success(res, activityArtist, '艺人添加成功');
    } catch (error) {
      next(error);
    }
  }

  // 从活动移除艺人
  async removeArtistFromActivity(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { activityId, artistId } = req.params;

      // 检查是否有投票数据
      const voteCount = await prisma.vote.count({
        where: {
          activityId: parseInt(activityId),
          artistId: parseInt(artistId)
        }
      });

      if (voteCount > 0) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ARTIST_HAS_VOTES, '该艺人在此活动中已有投票，无法移除');
        return;
      }

      await prisma.activityArtist.delete({
        where: {
          activityId_artistId: {
            activityId: parseInt(activityId),
            artistId: parseInt(artistId)
          }
        }
      });

      ResponseUtils.success(res, null, '艺人移除成功');
    } catch (error) {
      next(error);
    }
  }

  // 更新活动艺人排序
  async updateActivityArtistOrder(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { activityId } = req.params;
      const { artists } = req.body; // [{artistId, sortOrder}]

      // 验证输入数据
      if (!Array.isArray(artists) || artists.length === 0) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '艺人列表必须是有效的数组');
        return;
      }

      // 验证每个艺人的数据
      for (const item of artists) {
        if (typeof item.artistId !== 'number' || typeof item.sortOrder !== 'number') {
          ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, '艺人ID和排序顺序必须是数字');
          return;
        }
      }

      const updates = artists.map((item: any) => 
        prisma.activityArtist.update({
          where: {
            activityId_artistId: {
              activityId: parseInt(activityId),
              artistId: item.artistId
            }
          },
          data: { sortOrder: item.sortOrder }
        })
      );

      await prisma.$transaction(updates);

      ResponseUtils.success(res, null, '排序更新成功');
    } catch (error) {
      next(error);
    }
  }

  // 获取活动投票统计
  async getActivityVoteStatistics(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const activityId = parseInt(id);

      const activity = await prisma.activity.findUnique({
        where: { id: activityId },
        include: {
          activityArtists: {
            include: {
              artist: {
                select: {
                  id: true,
                  name: true,
                  avatar: true
                }
              }
            },
            orderBy: { sortOrder: 'asc' }
          }
        }
      });

      if (!activity) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.ACTIVITY_NOT_FOUND, '活动不存在');
        return;
      }

      // 获取每个艺人的投票统计
      const voteStats = await prisma.vote.groupBy({
        by: ['artistId'],
        where: { activityId },
        _sum: {
          voteCount: true
        },
        _count: {
          userId: true
        }
      });

      // 获取总体投票统计
      const totalVoteStats = await prisma.vote.aggregate({
        where: { activityId },
        _sum: {
          voteCount: true
        },
        _count: {
          userId: true
        }
      });

      // 合并数据
      const artistStats = activity.activityArtists.map(aa => {
        const voteStat = voteStats.find(vs => vs.artistId === aa.artist.id);
        return {
          artist: aa.artist,
          totalVotes: voteStat?._sum.voteCount || 0,
          uniqueVoters: voteStat?._count.userId || 0,
          sortOrder: aa.sortOrder
        };
      });

      // 按投票数排序
      artistStats.sort((a, b) => b.totalVotes - a.totalVotes);

      ResponseUtils.success(res, {
        activity,
        artistStats,
        totalVotes: totalVoteStats._sum.voteCount || 0,
        totalVoters: totalVoteStats._count.userId || 0
      }, '获取投票统计成功');
    } catch (error) {
      next(error);
    }
  }
}
